<template>
  <div>
    <a-icon v-if="isLoading" type="sync" spin theme="outlined" />
    <div v-else class="flex flex-row items-center cursor-pointer" @click="handleEdit">
      <component
        v-if="isEdit"
        :is="compName"
        @blur="blur"
        autoFocus
        :min="min"
        :max="max"
        :step="step"
        :value="editValue"
        :precision="precision"
        style="width: 100%; min-width: 80px"
        @change="change"
      />
      <span :class="{ 'p-1': editValue || editValue === 0 }" :style="labelStyle" v-else>{{ editValue }}</span>
    </div>
  </div>
</template>
<script lang="ts">
export default defineComponent({
  name: 'FocusInput',
})
</script>
<script setup lang="ts">
import { propTypes } from '@/utils/propTypes'
import { computed, onMounted, ref, defineComponent } from 'vue'

// 参数定义
const emits = defineEmits<{
  (event: 'change', value: number | string): void
}>()
/**
 * FocusInput 聚焦输入框组件
 */
const props = defineProps({
  // 编辑的类型
  mode: propTypes.string.def('input'),
  // 末尾的字符
  suffix: propTypes.string.def(''),
  // 值
  value: {
    type: [Number, String],
  },
  // 默认的最小值
  min: propTypes.number.def(0),
  // 最大值
  max: propTypes.number.def(Infinity),
  // 步进值
  step: propTypes.number.def(1),
  precision: propTypes.number.def(2),
  labelStyle: propTypes.object.def({}),
})

// 变量定义
const isEdit = ref(false)
const editValue = ref<any>(null)
const isLoading = ref(false)
// 需要渲染的组件
const compName = computed(() => `a-input${props.mode === 'input' ? '' : '-number'}`)

onMounted(() => {
  editValue.value = props.value
})

// 值的改变
const change = (e) => {
  switch (props.mode) {
    case 'input':
      editValue.value = e.target.value
      break
    case 'number':
      editValue.value = e.toFixed(props.precision)
      break
  }
}

// 改变状态
function handleEdit() {
  isEdit.value = true
}
// 取消编辑
function cancelEdit() {
  isEdit.value = false
}
// 鼠标移除后
function blur() {
  if (!isEdit.value || isLoading.value || props.value === editValue.value) return cancelEdit()
  isLoading.value = true
  emits('change', editValue.value)
  isLoading.value = false
  isEdit.value = false
}
</script>
